package com.nutshare.lt;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class Result
{

    private String number;
    private String dateStr;
    private Date date;


    private SimpleDateFormat inDateFormat = new SimpleDateFormat("dd.MM.yyyy");

    int capacity = 0; // max number 45 or 36
    int count = 0;  // 6 or 5
    HashSet<Integer> result = new HashSet<Integer>();
    HashSet<Pair> pairs = new HashSet<Pair>();
    HashSet<Tern> terns = new HashSet<Tern>();

    public Result(int capacity, int count, String number, String dateStr)
    {
        this.capacity = capacity;
        this.number = number;
        this.dateStr = dateStr;
        this.count = count;

        try
        {
            this.date = inDateFormat.parse(dateStr);
        }
        catch(ParseException e)
        {
            System.out.println("Failed to parse date " + dateStr);
        }


    }

    public Iterator<Integer> iterator()
    {
        return result.iterator();
    }

    public void parseString(String in)
    {
        in = in.trim();
        StringTokenizer s = new StringTokenizer(in, " ", false);

        while (s.hasMoreElements())
        {
            String next = s.nextToken();
            Integer parsed = null;
            try
            {
                parsed = Integer.parseInt(next);
            } catch (NumberFormatException e)
            {
                continue;
            }

            add(parsed);
        }
    }

    public boolean contains(Integer key)
    {
        return result.contains(key);
    }

    public void add(Integer toAdd)
    {
        result.add(toAdd);

        Iterator<Integer> i = result.iterator();

        while(i.hasNext())
        {
            Integer next = i.next();

            if(next.compareTo(toAdd) == 0)
            {
                continue;
            }

            Pair p = new Pair(next, toAdd);
            if(!p.isValid())
            {
                continue;
            }

            if(!pairs.contains(p))
            {
                pairs.add(p);
            }
        }

        Iterator<Pair> pi = pairs.iterator();
        while(pi.hasNext())
        {

            Pair nextPair = pi.next();
            Iterator<Integer> rIter = result.iterator();
            while(rIter.hasNext())
            {

                HashSet<Integer> pairSet = nextPair.getSet();

                Integer item = rIter.next();
                pairSet.add(item);

                Tern tern = new Tern(pairSet);

                if(!tern.isValid())
                {
                    continue;
                }

                if(!terns.contains(tern))
                {
                    terns.add(tern);
                }
            }
        }

    }

    public double getMatOzh()
    {
        Double sum = new Double(0);
        Iterator<Integer> i = result.iterator();
        while(i.hasNext())
        {
            Integer next = i.next();
            sum = new Double(sum.doubleValue()+next.doubleValue());
        }
        return sum.doubleValue() ; // / 45;
    }

    public double getAvg()
    {
        Double sum = new Double(0.0);
        Iterator<Integer> i = result.iterator();
        while(i.hasNext())
        {
            Integer next = i.next();
            sum = new Double(sum.doubleValue()+next.doubleValue());
        }
        return sum.doubleValue() / this.capacity;
    }


    public HashSet<Pair> getPairs()
    {
        return pairs;
    }

   public HashSet<Tern> getTerns()
    {
        return terns;
    }

    public boolean isValid()
    {
        return (capacity > 0 && result.size() == capacity);
    }

    public static class Pair implements Comparable
    {
        Integer left = null;
        Integer right = null;

        public Pair(Integer i1, Integer i2)
        {
            this(i1, i2, true);
        }

        public Pair(Integer i1, Integer i2, boolean order)
        {
            if(order)
            {
                if (i1 != null && i2 != null)
                {
                    if (i1.compareTo(i2) < 0)
                    {
                        left = i1;
                        right = i2;
                    }
                    else
                    {
                        left = i2;
                        right = i1;
                    }
                }
            }
            else
            {
                left = i1;
                right = i2;

            }
        }

        public boolean startsWith(Integer left)
        {
            return (this.left.equals(left));
        }

        public Integer getRight()
        {
            return right;
        }

        public boolean isValid()
        {
            return (left != null && right != null && left.intValue()!=right.intValue());
        }

        public int hashCode()
        {
            return (left.intValue() ^ (right.intValue() << 8));
        }

        public String toString()
        {
            return left.toString() + "-" + right.toString();
        }

        public boolean equals(Object i)
        {
            if( i == null || !(i instanceof  Pair))
            {
                return false;
            }

            return (this.hashCode() == i.hashCode());
        }

        public HashSet<Integer> getSet()
        {
            HashSet<Integer> set = new HashSet<Integer>();
            set.add(left);
            set.add(right);

            return set;
        }

        public int compareTo(Object o)
        {

            return 0;
        }
    }

  public static class Tern implements Comparable
    {
        TreeSet<Integer> values = new TreeSet<Integer>();

        public Tern(Integer i1, Integer i2, Integer i3)
        {
            if (i1 != null && i2 != null && i3!=null)
            {
                values.add(new Integer(i1));
                values.add(new Integer(i2));
                values.add(new Integer(i3));
            }
        }

        public Tern(HashSet<Integer> set)
        {
            if(set.size()==3)
            {
                values.addAll(set);
            }
            else
            {
                // System.out.println("ERROR>>>>" + set);
            }
        }

        public boolean isValid()
        {
            return (values.size()==3);
        }

        public int hashCode()
        {
            if(!isValid())
            {
                return -1;
            }

            int result = 0;
            int count = 0 ;
            Iterator<Integer> i = values.iterator();
            while(i.hasNext())
            {
                Integer v = i.next();
                result = result ^ (v.intValue() << count);
                count+=8;
            }

            return result;
        }

        public String toString()
        {
            String result = "";
            Iterator<Integer> i = values.iterator();
            while(i.hasNext())
            {
                if(!result.equals(""))
                {
                    result = result + "-";
                }

                result = result + i.next();
            }
            return result;
        }

        public boolean equals(Object i)
        {
            if( i == null || !(i instanceof Tern))
            {
                return false;
            }

            return (this.hashCode() == i.hashCode());
        }


        public int compareTo(Object o)
        {
            return 0;
        }
    }

    public String toString()
    {
        return number + "@" + inDateFormat.format(date) + " " + count + "x" + capacity + " " + result.toString();
    }

}
